#include "Segment.h"

Segment::Segment(unsigned id, BufferManager& manager, SegmentInventory& segInventory) : segmentId(id), pageCount(0), segmentInventory(segInventory), manager(manager)
{
    SEM_CREATE(segmentLock);
}

/**
Returns the page with the given index (index reffers to the index inside the segment)
*/
BufferFrame& Segment::getPage(unsigned index, bool exclusive)
{
    unsigned position = this->pageIds[index];
    return this->manager.getPage(position, exclusive);
}

/**
Returns how many pages are inside the segment
*/
unsigned Segment::getPageCount()
{
    return this->pageCount;
}


void Segment::unfixPage(BufferFrame& frame, bool dirty)
{
    this->manager.unfixPage(frame, dirty);
}

/**
Requests some pages. The number of pages is > min and < max. The actual number of pages is returned.
*/
vector<unsigned> Segment::requestPages(unsigned min, unsigned max)
{
    SEM_WRITELOCK(segmentLock);
    vector<unsigned> newPages = this->segmentInventory.requestPages(this->segmentId, min, max);
    vector<unsigned> result;
    this->pageCount += newPages.size();
    for (unsigned i = 0; i < newPages.size(); i++)
    {
        result.push_back(this->pageIds.size());
        this->pageIds.push_back(newPages[i]);
    }
    SEM_UNLOCK(segmentLock);
    return result;
}

/**
returns the Id of the segment
*/
unsigned Segment::getId()
{
    return this->segmentId;
}

Segment::~Segment()
{
    this->segmentInventory.returnPages(this->segmentId, this->pageIds);
    SEM_DESTROY(segmentLock);
}
